package com.xm9m.web.service.api;

import com.salesmanager.core.business.customer.model.Customer;
import com.salesmanager.core.business.customer.model.CustomerAuths;
import com.salesmanager.core.business.customer.model.CustomerCriteria;
import com.salesmanager.core.business.customer.service.CustomerService;
import com.salesmanager.core.modules.cache.Xm9mRedisTemplateSupport;
import com.salesmanager.core.utils.DateUtil;
import com.salesmanager.web.utils.SMS.JavaSmsApi;
import com.xm9m.web.service.api.request.LoginRequest;
import com.xm9m.web.service.api.response.LoginResponse;
import com.xm9m.web.service.constants.APIConstants;
import com.xm9m.web.service.constants.ResultMessage;
import com.xm9m.web.service.constants.StatusCode;
import com.xm9m.web.service.entity.TokenInfo;
import com.xm9m.web.service.entity.UserInfo;
import com.xm9m.web.service.entity.security.SecurityCustomer;
import com.xm9m.web.service.interfaces.AbstractRestApi;
import com.xm9m.web.service.interfaces.IXm9mResponse;
import com.xm9m.web.service.internal.util.BuildResponseUtil;
import com.xm9m.web.service.utils.GenerateNick;
import net.sf.json.JSONObject;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AnonymousAuthenticationToken;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.WebAuthenticationDetails;
import org.springframework.security.web.context.HttpSessionSecurityContextRepository;

import javax.annotation.Resource;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;


public class CustomerLogon extends AbstractRestApi {

    private static final Logger logger = LoggerFactory.getLogger(CustomerLogon.class);

    @Autowired
    AuthenticationManager authenticationManager;

    @Autowired
    private CustomerService customerService;

    @Resource
    private Xm9mRedisTemplateSupport redisTemplate;

    @SuppressWarnings("unchecked")
    @Override
    public <T extends IXm9mResponse> T execute(String requestData, String version) throws Exception {
        LoginResponse loginResponse = new LoginResponse();

        String userName;
        String password;
        LoginRequest loginRequest = super.json2Bean(requestData, LoginRequest.class);
        if (loginRequest == null) {
            return (T) BuildResponseUtil.buildSimpleResponse(StatusCode.PARAM_WRONG);
        }
        boolean testSve = redisTemplate.EXISTS("testSve");
        System.out.println(testSve);
        redisTemplate.SET("testSve","liutong");
        Object testSve1 = redisTemplate.GET("testSve");
        System.out.println(testSve1);

        StringBuffer url = httpServletRequest.getRequestURL();
        String tempContextUrl = url.delete(url.length() - httpServletRequest.getRequestURI().length(), url.length()).
                append(httpServletRequest.getContextPath()).append("/").toString();
        String tokenUrl = tempContextUrl + APIConstants.Customer.TOKEN_GET;

        boolean success = false;
        //用户名密码登陆
        if (loginRequest.getType() == 1) {
            success = customerService.validateCustomer(loginRequest.getUsername(), loginRequest.getPassword());
//            //按设备ID查询
//            CustomerAuths customerAuths = customerService.getCustomerAuthByDeviceId(loginRequest.getDeviceId());
//
//            //判断改设备是否被其他手机绑定过
//            if (customerAuths != null && customerAuths.getCustomer() != null && customerAuths.getCustomer().getTelphone() != null && !customerAuths.getCustomer().getTelphone().equals(loginRequest.getUsername())) {
//                return (T) BuildResponseUtil.buildSimpleResponse(StatusCode.DEVICE_ALREADY_BIND);
//                //未绑定设备，这里需绑定
//            } else if (customerAuths == null) {
//                Customer customer = customerService.getByTelphone(loginRequest.getUsername());
//                CustomerAuths newAuth = new CustomerAuths();
//                newAuth.setIdentityType(2);
//                newAuth.setIdentifier(loginRequest.getDeviceId());
//                newAuth.setStatus(1);
//                newAuth.setCreateTime(new Date());
//                newAuth.setCustomer(customer);
//
//                String diffDevice = customer.getDiffDevice();
//                int tag = 0;
//
//                String thisMonth = DateUtil.getMonth();//本月
//                String month = null;
//                Integer times = null;
//
//                for (CustomerAuths auths : customer.getAuths()) {
//
//                    //已经绑定了设备  ，更新设备ID
//                    if (auths.getIdentityType() == 2) {
//                        if (!StringUtils.isBlank(diffDevice)) {
//                            month = diffDevice.split(",")[0];//月份
//                            times = Integer.parseInt(diffDevice.split(",")[1]);//次数
//                            //单个自然月内，换绑超过两次，则提示不让换绑
//                            if (thisMonth.equals(month)) {
//                                if (times == 2) {
//                                    return (T) BuildResponseUtil.buildSimpleResponse(StatusCode.CHANGE_DEVICE);
//                                }
//                            } else {
//                                month = thisMonth;
//                                times = 0;
//                            }
//                        } else {
//                            month = thisMonth;
//                            times = 0;
//                        }
//
//                        auths.setIdentifier(loginRequest.getDeviceId());
//                        times = times + 1;
//                        String newDiffDevice = month+","+times;
//                        customer.setDiffDevice(newDiffDevice);
//                        tag = 1;
//                        break;
//                    }
//                }
//                //没有绑定过设备
//                if (tag == 0) {
//                    customer.getAuths().add(newAuth);
//                }
//                customerService.update(customer);
//            }

            //一键登陆 deviceId登陆
        } else if (loginRequest.getType() == 2) {
            if (loginRequest.getDeviceId() == null) {
                success = false;
            } else {
                success = customerService.getCustomerAuthByDeviceId(loginRequest.getDeviceId()) != null;

                //用户不存在 直接创建
                if (!success) {
                    CustomerCriteria customerCriteria = new CustomerCriteria();
                    customerCriteria.setAuthType(2);
                    customerCriteria.setDeviceId(loginRequest.getDeviceId());
                    customerCriteria.setNick(GenerateNick.generate());
                    customerCriteria.setMasterId(loginRequest.getMasterId());
                    customerCriteria.setChannel(loginRequest.getChannel());
                    customerService.saveSignUpUser(customerCriteria);
                    success = true;
                }

            }
        } else {
            success = false;
        }

        //自动登录
        if (success) {
            //保存设备唯一标识和APP_KEY
            String deviceToken = null;
            String appKey = null;
            if (!StringUtils.isBlank(loginRequest.getDeviceToken()) && loginRequest.getDeviceToken().length() > 30) {
                deviceToken = loginRequest.getDeviceToken();
            } else {
                logger.error("deviceToken invalid:{}", loginRequest.getDeviceToken());
            }

            //保存AppKey
            if (!StringUtils.isBlank(loginRequest.getAppKey())) {
                appKey = loginRequest.getAppKey();
            }

            boolean r1 = customerService.saveDeviceToke(loginRequest.getUsername(), deviceToken, appKey);
            if (!r1) {
                logger.error("save deviceToken failed");
            }


            //spring security 自动登录
            UsernamePasswordAuthenticationToken token;
            if (loginRequest.getType() == 1) {
                userName = loginRequest.getUsername();
                password = loginRequest.getPassword();
                token = new UsernamePasswordAuthenticationToken(userName, password);
            } else {
                userName = "deviceId:" + loginRequest.getDeviceId();
                password = loginRequest.getDeviceId();
                token = new UsernamePasswordAuthenticationToken(userName, password);
            }

            try {
                token.setDetails(new WebAuthenticationDetails(httpServletRequest));
                Authentication authenticatedUser = authenticationManager.authenticate(token);
                SecurityContextHolder.getContext().setAuthentication(authenticatedUser);
                httpServletRequest.getSession().setAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY, SecurityContextHolder.getContext());
                //用户名
                String nick;
                Authentication auth = SecurityContextHolder.getContext().getAuthentication();
                if (!(auth instanceof AnonymousAuthenticationToken)) {
                    SecurityCustomer userDetails = (SecurityCustomer) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
                    nick = userDetails.getNick();
                    UserInfo userInfo = new UserInfo();
                    userInfo.setNick(nick);
                    userInfo.setId(userDetails.getCustomerId());
                    loginResponse.setUserInfo(userInfo);

                }

                //oauth2自动登录
                Map<String, String> properties = new HashMap<String, String>();
                properties.put("client_id", "app-client");
                properties.put("client_secret", "app");
                properties.put("grant_type", "password");
                properties.put("scope", "read");
                properties.put("username", userName);
                properties.put("password", password);
                String ss = JavaSmsApi.post(tokenUrl, properties);
                JSONObject json = JSONObject.fromObject(ss);
                if (!StringUtils.isBlank((String) json.get("access_token"))) {
                    TokenInfo tokenInfo = new TokenInfo();
                    tokenInfo.setAccess_token((String) json.get("access_token"));
                    tokenInfo.setExpires_in(Integer.parseInt(json.get("expires_in").toString()));
                    tokenInfo.setRefresh_token((String) json.get("refresh_token"));
                    tokenInfo.setToken_type((String) json.get("token_type"));
                    loginResponse.setTokenInfo(tokenInfo);
                }
                loginResponse.setMessage(StatusCode.SUCCESS.getMessage());
                loginResponse.setSuccessful(ResultMessage.TRUE);
                loginResponse.setCode(StatusCode.SUCCESS.getCode());
                return (T) loginResponse;

            } catch (Exception e) {
                logger.error("自动登录失败！", e);
            }
        }
        return (T) BuildResponseUtil.buildSimpleResponse(StatusCode.LOGIN_ERROR);
    }
}
